package com.mtiiot.util;

import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Des3 {
	private static Logger logger = LogManager.getLogger(Des3.class);

    /**
     * CBC加密
     * @param key 密钥
     * @param keyiv IV
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception
     */
    public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * CBC解密
     * @param key 密钥
     * @param keyiv IV
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception
     */
    public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data)
            throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv);
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    
   public static String getUUID(){    
       String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");    
       return uuid;    
   } 
    
    /**
     * 服务器器端使用
     * 获取动态密码和当前时间(采用CBC加密后取密文的后2,3,4,5,6,7位为动态密码)
     * @param dynamicPwd 动态密码
     * @param insPwd  仪器对应密码
     * @param timeStr 时间字符串
     * @return
     */
    public static boolean validateDynamicPwd(String dynamicPwd,String insPwd,String timeStr){
    	try {
    		String data=insPwd+timeStr;
    		byte[] Bytekey=new BASE64Decoder().decodeBuffer(Constants.key);
    		byte[] byteDe=Des3.des3EncodeCBC(Bytekey, Constants.keyiv,data.getBytes("UTF-8"));
    		String strDe=new BASE64Encoder().encode(byteDe);
    		String strDe1=strDe.substring(strDe.length()-7, strDe.length()-1);
    		return dynamicPwd.equals(strDe1);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return false;
		}
    	
    }
    
    /**
     * 客户端使用
     * 获取动态密码和当前时间(采用CBC加密后取密文的后2,3,4,5,6,7位为动态密码)
     * @param insPwd  仪器对应密码
     * @return
     *  String[0] 为动态密码(6位)
     *  String[1] 位时间戳(精确到毫秒):格式yyyMMddHHmmssSSS
     */
    public static String[] getDynamicPwd(String insPwd){
    	try {
    		String[] str=new String[2];
    		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmssSSS");
        	String timeStr=sdf.format(new Date());
    		String data=insPwd+timeStr;
    		byte[] Bytekey=new BASE64Decoder().decodeBuffer(Constants.key);
    		byte[] byteDe=Des3.des3EncodeCBC(Bytekey, Constants.keyiv,data.getBytes("UTF-8"));
    		String strDe=new BASE64Encoder().encode(byteDe);
    		System.out.println(strDe);
    		String strDe1=strDe.substring(strDe.length()-7, strDe.length()-1);
    		str[0]=strDe1;
    		str[1]=timeStr;
    		System.out.println(str[0]);
    		System.out.println(str[1]);
    		return str;
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
    	
    }
    
    public static void main(String[] args) throws Exception {
    	String insPwd=Des3.getUUID();
    	for(int i=0;i<20;i++){
    		String[] strArr=Des3.getDynamicPwd(insPwd);
        	System.out.println(Des3.validateDynamicPwd(strArr[0], insPwd, strArr[1]));
    	}
    	
    	 // String time=
//        byte[] key=new BASE64Decoder().decodeBuffer("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");
//        byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
//        byte[] data="YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd".getBytes("UTF-8");
//        
//        System.out.println("ECB加密解密");
//        byte[] str3 = des3EncodeECB(key,data );
//        byte[] str4 = ees3DecodeECB(key, str3);
//        System.out.println(new BASE64Encoder().encode(str3));
//        System.out.println(new String(str4, "UTF-8"));
//        System.out.println();
//        System.out.println("CBC加密解密");
//        byte[] str5 = des3EncodeCBC(key, keyiv, data);
//        byte[] str6 = des3DecodeCBC(key, keyiv, str5);
//        System.out.println(new BASE64Encoder().encode(str5));
//        System.out.println(new String(str6, "UTF-8"));
    }
}
